默认权限的比较
Java | Cpp | 备注 | |
---|---|---|---|
权限关键字 | public、protect、default、private | public、protect、friend、private | Cpp中friend实际打破了类的封装 |
默认权限 | default(friendly) 仅内部和同包(有继承)可以使用 | private,仅内部可以使用,继承类和子类均无法使用 | 参考链接_带实例 ,参考链接2 |
对外可见性 | Java通过包名定义可见范围,没有全局变量 | 通过命名空间定义,有全局变量 |
多态实现
- Java中是除了static ,final,private等可以在编译器确定的类别外,其余都是在后期绑定 ,Cpp中是前期绑定。 Java中继承类是父类的一种新类型
- Cpp通过virtual 虚函数完成动态绑定
1 | class Shape { |
输出结果1
2Circle.draw()
Square.draw()
可以看出,Java中通过后期绑定的方法,在继承类中改写父类信息,可以直接通过父类访问子类变量和函数。
1 | class Shape { |
输出结果1
2Shape draw()
Shape draw()
如果需要完成动态绑定,得到Java程序的输出,需要添加vitrual,将Shape改成如下形式;1
2
3
4
5
6
7class Shape {
public:
virtual void draw() {
cout << "Shape draw()" << endl;
}
};
需要注意的是,基于指针的虚函数表,只有存在指针的时候虚函数才会改变指向,如上采用如下方式1
2
3
4
5
6
7
8int main() {
Shape s1 =Circle(),s2= Square();
s1.draw();
s2.draw();
system("pause");
return 0;
}
永远都是输出Shape的信息,因为s1,s2定义在栈空间,只会存在栈顶指针的移动。
重载与重写
- 重写需要保证函数名,返回值,参数列表一致(Cpp与Java相同)
- Java中的重载可以跨越子类与继承类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36class A_base{
public final static int static_value =1;
}
class Shape {
void draw() {
}
void draw(int x) {
System.out.println("Shape draw");
}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
//实际是重载
void draw(A_base x) {
System.out.println("Circle draw");
}
}
public class test {
public static void letsdarw(Shape s) {
s.draw(A_base.static_value);//实际调用的是s.draw(int value)
}
public static void main(String[] args) {
Circle circle = new Circle();
A_base a_base = new A_base();
circle.draw(a_base);
letsdarw(circle);
}
}
输出结果1
2Circle draw
Shape draw